#version 460
#extension GL_EXT_nonuniform_qualifier : enable
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
//#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require
#extension GL_ARB_shader_clock : enable

#include "../../../core/shader_std.h"
#include "../../../core/shader_built_in_functions.h"



layout(location = 0) in vec4 vColor;
layout(location = 1) in vec2 vUV;
layout(location = 2) in flat uint vLayerNum;
//layout(location = 3) in flat uint layerOffset;

layout(location=0) out vec4 outColor;



layout(set = 3, binding = DEF_binding_L3_ArrayImage, rgba8) uniform image2D		image[];
layout(set = 3, binding = DEF_binding_L3_ArraySampler)		uniform sampler2D	tex[];

layout(std140, set = 4, scalar, column_major, binding = DEF_binding_L4_LayerArea) uniform U_0 {
	S_FrameSample_TAA m_LayerArea[DEF_UI_LayerAreaNum];
};
layout(std140, set = 4, scalar, column_major, binding = DEF_binding_L4_SampleAA) uniform U_1 {
	S_FrameSample_TAA m_SamplerAttr[DEF_UI_LayerNum];
};



void main(void) {
	vec4 blurColor = vec4(0);
	const vec2 texSize = vec2(imageSize(image[0]));
	const ivec2 uv = ivec2(vUV * texSize);
	const vec2 offset = 1 / texSize;

	float aBlur = 0;

	outColor = vec4(vec3(0), 0);
	//return;
	//vec4 color[8];
	
	//outColor = vec4(vec3(imageLoad(image[1], uv)), 1);
	//vec4 c = texture(tex[1 * 3], vUV);
	//outColor = vec4(vec3(c.a), 1);
	//return;
	/*for ( int i = 0; i < vLayerNum; ++i ) {
		vec4 layerColorTex = imageLoad(image[i], uv);
		outColor.rgb = mix(outColor.rgb, layerColorTex.rgb, layerColorTex.a);
		outColor.a = min(layerColorTex.a + outColor.a, 1);
	}
	return;*/
	
	uint franeCount;
	uint layerID = 0;
	
	
	for ( int i = 0; i < vLayerNum; ++i ) {
		vec4 colorBack = imageLoad(image[i], uv);
		
		uint layerOffset;
		uint areaNum;
		glsl_FrameSampleLayerAttr(m_SamplerAttr[i], franeCount, layerOffset, areaNum);
		const uint index = i * 3;
		
		for ( uint ia = 0; ia < areaNum; ++ia ) {
			uvec2 frameOffset;
			uvec2 frameSize;
			bool isUpdate;
			uint debug;
			glsl_UnPack_LayerArea(m_LayerArea[layerOffset + ia], frameOffset, frameSize, isUpdate, debug);
			
			if ( all(greaterThanEqual(uv, frameOffset)) && all(lessThan(uv, frameSize)) ) {
				vec4 blur = texture(tex[index + 2], vUV);

				
				if (blur.r > 0) {
					colorBack = mix(blurColor, colorBack, colorBack.a);
					colorBack.a = min(colorBack.a + blur.r, 1);
					//colorBack = blurColor;
				}
				
				outColor.rgb = mix(outColor.rgb, colorBack.rgb, colorBack.a);
				outColor.a = min(colorBack.a + outColor.a, 1);

				vec4 blurSample = texture(tex[index], vUV + offset * 0);
				//blurColor = mix(blurColor, blurSample, blurSample.a);
				blurColor.rgb += blurSample.rgb * blurSample.a;
				blurColor.a += blurSample.a;
				
				break;
			}
		}
	}
	return;

	/*for ( int i = 0; i < vLayerNum; ++i ) {
		vec4 colorBack = imageLoad(image[i], uv);
		uint index = i * 3;

		
		vec4 blur = texture(tex[index + 2], vUV);

		if (blur.r > 0) {
			vec4 blurSample = texture(tex[index], vUV + offset);
			blurColor = mix(blurColor, blurSample, blurSample.a);

			colorBack = mix(blurColor, colorBack, colorBack.a);
			colorBack.a = min(colorBack.a + blur.r, 1);
		}
		
		outColor.rgb = mix(outColor.rgb, colorBack.rgb, colorBack.a);
		outColor.a = min(colorBack.a + outColor.a, 1);
	}
	return;*/

	int i = int(vLayerNum) - 1;
	for ( ; i >= 0; --i ) {
		if(outColor.a >= 1) break;
		//aBlur = max(aBlur, blur.r);
		uint layerOffset;
		uint areaNum;
		glsl_FrameSampleLayerAttr(m_SamplerAttr[i], franeCount, layerOffset, areaNum);
		const uint index = i * 3;

		for ( uint ia = 0; ia < areaNum; ++ia ) {
			uvec2 frameOffset;
			uvec2 frameSize;
			bool isUpdate;
			//glsl_UnPack_LayerArea(m_LayerArea[layerOffset + ia], frameOffset, frameSize, isUpdate);
			
			if ( all(greaterThanEqual(uv, frameOffset)) && all(lessThan(uv, frameSize)) ) {
				
				vec4 colorCurrent = imageLoad(image[i], uv);
				//if(colorBack.a <= 0) break;
				
				vec4 blurSample = texture(tex[index], vUV + offset * 0);
				//blurColor = mix(blurColor, blurSample, blurSample.a);
				blurColor.rgb += blurSample.rgb * blurSample.a;
				blurColor.a += blurSample.a;
				
				vec4 blur = texture(tex[index + 2], vUV);
				aBlur += blur.r;
				
				if (blur.r > 0) {
					colorCurrent = mix(blurColor, colorCurrent, colorCurrent.a);
					colorCurrent.a = min(colorCurrent.a + blur.r, 1);
					//colorBack = blurColor;
				}
				
				outColor.rgb = mix(outColor.rgb, colorCurrent.rgb, colorCurrent.a);
				outColor.a = min(colorCurrent.a + outColor.a, 1);

				
				break;

				if (aBlur > 0 && i > 0) {
					vec4 blurSample = texture(tex[index], vUV + offset*0.0);
					
					if (blurSample.a <= 0) {
						outColor.rgb += vec3(0.2, 0, 0);
						break;
					}
					//colorCurrent.rgb = mix(blurSample.rgb, colorCurrent.rgb, outColor.a > 0.000001 ? outColor.a : colorCurrent.a);
					
					//aBlur = aBlur - blurSample.a;
					if (layerID > 0) {
						//colorCurrent.rgb = colorCurrent.rgb * colorCurrent.a + blurSample.rgb * (1-outColor.a);
						//colorCurrent.a += blurSample.a;

						//blurSample.rgb *= (1-outColor.a) * blurSample.a;
						//blurSample.a += outColor.a;

						//colorCurrent.rgb = mix(colorCurrent.rgb, blurSample.rgb, blurSample.a);
						//colorCurrent.a += blurSample.a;

						colorCurrent = blurSample;
						colorCurrent.rgb += vec3(0, 0.3, 0.0);
						//colorCurrent.a += outColor.a;
					}
					else {
						colorCurrent.rgb = mix(blurSample.rgb * blurSample.a, colorCurrent.rgb, colorCurrent.a);
						colorCurrent.a += blurSample.a;
						colorCurrent.rgb += vec3(0, 0.0, 0.3);
					}
					
					

					outColor.rgb = mix(colorCurrent.rgb, outColor.rgb, outColor.a);
					outColor.a += colorCurrent.a;
					//outColor.a = min(outColor.a + blurSample.a, 1);

					aBlur += colorCurrent.a;
				}
				else{
					outColor.rgb = mix(colorCurrent.rgb, outColor.rgb, outColor.a);
					outColor.a = min(colorCurrent.a + outColor.a, 1);

					outColor.rgb += vec3(0.3, 0.3, 0.0);
				}
				

				
				
				++layerID;
				break;
			}
			
		}
		
		//outColor = vec4(vec3(imageLoad(image[i], uv)), 1);
		//if(outColor.a >= 1) break;
		//break;
	}
	
}


// textureGather()